Skip to content

Conversation

@jolting
Copy link
Member

@jolting jolting commented Nov 27, 2025

Changed apps/libraries

  • mrpt-math

PR Description

Errors in
TObject3D::generate2DObject()
TObject2D::generate3DObject()

Like this

error C2440: 'return': cannot convert from 'initializer list' to 'mrpt::math::TObject2D'

I acknowledge to have:

(Notify: @MRPT/owners )

@jolting
Copy link
Member Author

jolting commented Nov 27, 2025

This behavior appears to have changed in c++20.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1008r1.pdf

It may be better to simply remove

  TObject2D() = default;

@jlblancoc
Copy link
Member

Oh, good to know! Adding such "=default;" was once upon a time the recommendation by C++ gurus... 🙄 🤣

@jlblancoc jlblancoc merged commit 179b79a into MRPT:3.0 Nov 27, 2025
0 of 6 checks passed
@jolting
Copy link
Member Author

jolting commented Dec 1, 2025

@jlblancoc I think that there is a nuance there that is missing. You're depending on a List-initialization. That is what removing the default allows.

There are two worlds. World 1: The Aggregate (The "Plain Struct") vs World 2: The Encapsulated Class. The guidance really depends on which world you are targeting.

struct A { int x, y; };
static_assert(std::is_aggregate_v<A>);
 
struct B
{
    B() = default;
};
static_assert(not std::is_aggregate_v<B>);

Defaulting the constructor puts you in World 2.

I think aggregate initialization gets confused with std::initializer_list

Feature           | Requires              | Compatible with Custom Constructors?
Widget w = {1, 2} | Aggregate             | No
Widget w = {.x=1} | Aggregate             | No
Widget w = {1, 2} | std::initializer_list | Yes (Only via list logic)

Another thing to consider is optimization.

Aggregates guarantee the object is just a memory layout. They are easiest for the optimizer to reason about, easiest to put in .rodata and easiest to pass via registers. If performance is critical then this is something to consider.

Constructors rely on Inlining to achieve parity, which may not produce the same optimal results. This really does depend on your compiler.

Perhaps the guidance should be use default if there are any other constructors defined.

@jlblancoc
Copy link
Member

Excellent clarifications.

I have been (rarely) using the aggregated-based initializers (as in old C) without taking care of it not being confused with initializer_list. 👍

Named params is still the only feature of Python that I miss in std C++...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants